#pragma once
#include "Socket.hpp"
#include <memory>
#include "Commn.hpp"
#include <strings.h>
#include <functional>
#include <sys/wait.h>
#include "ThreadPool.hpp"


namespace TcpserverModule
{
    using namespace SocketModule;
    using TcpHandler_t = std::function<void(SockPtr sock, InetAddr client)>;
    using task_t = std::function<void(void)>;
    class TcpServer
    {
    public:
        TcpServer(int port)
            : _port(port),
              _sock(std::make_unique<Tcpsocket>()),
              _isrunning(false)
        {
            // 创建tcp服务
            _sock->BuildTcpserver(_port);
        }
        void RegisterHandler(TcpHandler_t Handler)
        {
            _handler = Handler;
        }
        void Loop()
        {
            _isrunning = true;
            while (_isrunning)
            {
                sockaddr_in client_addr;
                bzero(&client_addr, sizeof(client_addr));
                // accept
                SockPtr ret = _sock->accpetor(&client_addr);
                InetAddr client(client_addr);
                
                auto p = ThreadPool<task_t>::GetInstance();
                task_t t = [this,ret,client](){ _handler(ret,client);};
                p->Push(t);
                // 开始处理任务
                // 在accpet之后再fork。
                // pid_t fd = fork();
                // if (fd == 0)
                // {
                //     // LOG(LogLevel::INFO) << "子进程关闭的文件描述符: " << ret->FD();
                //     _sock->Close(); // 子进程关闭listen
                //     if (fork() > 0)
                //         exit(0);
                //     // LOG(LogLevel::INFO) << "孙子进程pid: " << getpid();
                //     // 孙子进程
                //     _handler(ret, client); //为什么要把这个交给上层来调用呢? 如果就在这里调用会怎样? 
                //     //我们Tcp只负责通信，真正的信息处理交给上层 
                //     ret->Close();
                //     exit(0);
                // }
                // // LOG(LogLevel::INFO) << "父进程关闭的文件描述符: " << ret->FD();
                // ret->Close(); // 父进程关闭accpet
                // pid_t wid = waitpid(fd, nullptr, 0);
                // (void)wid;
            }
            _isrunning = false;
        }
        ~TcpServer() {}

    private:
        int _port;
        std::unique_ptr<Socket> _sock;
        bool _isrunning;
        TcpHandler_t _handler;
    };
}
